package com.atguigu.tingshu;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * @author: atguigu
 * @create: 2024-05-12 14:08
 */
@Slf4j
@SpringBootTest
public class RedisssonLockDemo {


    @Autowired
    private RedissonClient redissonClient;


    @Test
    public void testLock() throws IOException {
        //1.创建锁对象
        RLock myLock = redissonClient.getLock("myLock");

        //2.模拟两个线程争抢获取锁
        new Thread(() -> {
            //2.1 获取锁成功执行业务
            myLock.lock();
            try {
                log.info("线程：{}获取锁成功,执行业务中...需要分钟（模拟业务超时）", Thread.currentThread().getName());
                //模拟再次加锁
                myLock.lock();
                log.info("线程：{} 再次获取锁成功，执行第二业务", Thread.currentThread().getName());
                myLock.unlock();

                log.info("线程：{}执行业务其他逻辑");
                TimeUnit.MINUTES.sleep(5);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                //释放锁
                myLock.unlock();
            }

        }, "ThreadA").start();
        ;

        new Thread(() -> {
            //2.1 获取锁成功执行业务
            myLock.lock();
            try {
                log.info("线程：{}获取锁成功,执行业务中...", Thread.currentThread().getName());
                TimeUnit.MINUTES.sleep(5);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                //释放锁
                myLock.unlock();
            }
        }, "ThreadB").start();
        ;


        System.in.read();
    }


    @Test
    public void test1() {
        //1.创建锁对象
        RLock myLock = redissonClient.getLock("myLock");
        myLock.lock();
        try {
            log.info("线程：{}获取锁成功,执行业务中...需要分钟（模拟业务超时）", Thread.currentThread().getName());

            //模拟再次加锁-一直阻塞到当前线程加锁成功为止
            myLock.lock();
            log.info("线程：{} 再次获取锁成功，执行第二业务", Thread.currentThread().getName());
            myLock.unlock();

            log.info("线程：{}执行业务其他逻辑");
            TimeUnit.MINUTES.sleep(5);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            myLock.unlock();
        }
    }

}
